import { Component, OnInit, Output, Input, EventEmitter, Injector, ViewChild, TemplateRef } from '@angular/core';
import { NotifyService } from '@farris/ui-notify';
import { DeclarationCommand, DgControl, DomService, FormBasicService } from '@farris/designer-services';
import { cloneDeep } from 'lodash-es';
import { HttpClient, HttpHeaders } from '@angular/common/http';

export class ImportCmpEditorParam {
  /** 导入组件的原容器类型 */
  containerType: string;
  /** 导入组件的原容器id */
  containerId: string;
  /** 组件使用独立脚本加载 */
  useIsolateJs?: boolean;
  /** 表单路径 */
  relativePath?: string;
  /** 表单名称 */
  name?: string;
}

@Component({
  selector: 'app-import-cmp',
  templateUrl: './import-cmp.component.html',
  styleUrls: ['./import-cmp.component.css']
})

export class ImportCmpComponent implements OnInit {
  /** 原始数据 */
  formData: any;
  /** 搜索框输入值 */
  searchValue: string;
  groupIcon = '<span class="k-icon k-i-search"></span>';
  /** 当前选中的展示数据 */
  chooseRecommand: boolean = true;
  /** 用户选择的数据 */
  selectedCommand: any;
  /** 推荐数据 */
  formRecommandData: any;
  /** 全部数据*/
  formAllData;
  /** 弹窗设定值 */
  modalConfig = {
    title: '选择表单',
    width: 950,
    height: 500,
    minWidth: 650,
    minHeight: 300,
    resizable: false,
    showButtons: true,
    showMaxButton: false
  };
  /** “全部”数据的副本 */
  formAllDataCopy;

  /** 启用服务器端分页 */
  pagerOnServer = false;
  /** 每页记录数 */
  pageList = [21, 50, 100];
  /** 当前页码 */
  pageIndex = 1;
  /** 每页记录数 */
  pageSize = 21;
  /** 分页区高度 */
  pagerHeight = 56;
  /** 显示每页记录数 */
  showPageList = false;
  /** 显示分页信息 */
  showPageInfo = true;
  /** 显示页码 */
  showPageNumber = true;
  /** 显示页码最大数量 */
  pagerLabelSize = 7;
  /** 总记录数 */
  total = 0;
  /** 是否支持分页 */
  supportPaging = true;
  paginationOptions = {
    id: 'Farris-formMetadata-Pagination_',
    itemsPerPage: this.pageSize,
    currentPage: this.pageIndex,
    pageList: this.pageList,
    totalItems: this.total,
    remote: this.pagerOnServer
  };
  /** 推荐中是否没有数据  */
  noRecommandData: boolean = false;
  /** 全部中是否没有数据  */
  noAllData: boolean = false;
  // 模态框关闭
  @Output() closeModal = new EventEmitter<any>();
  // 模态框确定后关闭，并传递参数
  @Output() submitModal = new EventEmitter<any>();
  @Input() value;
  @Input() editorParams: ImportCmpEditorParam;
  @ViewChild('footer') modalFooter: TemplateRef<any>;
  metadataPath = '';
  oldCmpId = '';

  // 当前环境是否设计时
  isDeisgnerEnv = true;

  constructor(
    private formBasicService: FormBasicService, private domService: DomService, public injector: Injector,
    private notifyService: NotifyService) { }

  ngOnInit() {
    this.formData = [];
    this.getAllDataInfo();
    this.getRecommandDataInfo();
    this.chooseRecommand = true;
    this.formAllDataCopy = [];
    if (this.value) {
      this.oldCmpId = this.value;
    }
    this.onSearchValueChanged('');
  }


  /**
   * 获取全部数据
   */
  getAllDataInfo() {
    const http = this.injector.get(HttpClient);
    const relativePath = this.editorParams.relativePath;
    // pagesize设为1000，如果调取的总数超过这个值，则再次调取一次，否则保留当前值；
    // 搜索逻辑修改为：保留formData，在全部页面搜索时，foreach的数据是formData；然后将搜索到的值显示，并关闭分页；
    // const pageSize = 1000;
    return http.get('/api/dev/main/v1.0/mdservice/unionmdlist?path=' + relativePath + '&pageIndex=1&pageSize=1000&metadataTypeList=.frm', {
      headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
      responseType: 'json'
    }).subscribe(data => {
      this.reinvokeInterface(data);
      this.formAllData = cloneDeep(this.getFormData(data, 'all'));
      this.formAllDataCopy = cloneDeep(this.formAllData);
    });
  }


  /** 获取推荐数据 */
  getRecommandDataInfo() {
    const http = this.injector.get(HttpClient);
    const relativePath = this.editorParams.relativePath;
    // 推荐
    return http.get('/api/dev/main/v1.0/mdservice/metadataListInSu?path=' + relativePath + '&metadataTypeList=.frm', {
      headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
      responseType: 'json'
    }).subscribe(data => {
      this.formRecommandData = cloneDeep(this.getFormData(data, 'recommand'));
      if (this.formRecommandData) {
        if (this.formRecommandData.length) {
          this.showRecommandData();
          this.getUniqueData(this.formData);
        }
      }
    });
  }
  /** 获取数据 */
  getFormData(data, category) {
    let metadata = [];
    const formMetadata = data['metadataIndexItems'] ? data['metadataIndexItems'] : data;
    if (formMetadata) {
      formMetadata.forEach(function (formMetadataItem, index) {
        let formMetadataItemTemp = {
          id: index,
          name: formMetadataItem.name,
          label: formMetadataItem.code,
          source: formMetadataItem.nameSpace,
          hide: false,
          active: false,
          data: formMetadataItem,
          category: category
        }
        metadata.push(formMetadataItemTemp);
      });
    }
    return metadata;
  }

  /** 展示“推荐”一栏 */
  showRecommandData() {
    this.selectedCommand = undefined;
    this.chooseRecommand = true;
    this.formData = [];
    if (this.formRecommandData) {
      if (this.formRecommandData.length) {
        this.formRecommandData.forEach(formRecommandDataItem => {
          this.formData.push(cloneDeep(formRecommandDataItem));
        });
      }
    }
    this.getUniqueData(this.formData);
    this.formData = this.onSearchValueChanged(this.searchValue);
  }

  /** 展示“全部”一栏 */
  showAllData() {
    this.selectedCommand = undefined;
    this.chooseRecommand = false;
    this.formData = this.onSearchValueChanged(this.searchValue);
  }

  /**
* 处理用户搜索值
* @param searchValue 用户搜索值
* @returns 
*/
  public handleSearchedValue(searchValue: any) {
    searchValue = searchValue == undefined ? '' : searchValue;
    searchValue = searchValue['originalEvent'] != undefined ? searchValue.value || '' : searchValue;
    this.searchValue = searchValue;
    this.supportPaging = this.searchValue == '' ? true : false;
    let value = searchValue.replace(/ /g, '').replace(/>/g, '');
    value = value == '' ? ' ' : value;
    value = value.toLowerCase();
    return value;
  }

  /**
  * 检测推荐中是否有值：包括本地元数据及最近
  * @param searchedData 
  */
  public checkValueExists(searchedData: any, value: any) {
    // 检测推荐元数据中是否有值
    const checkRecommand = searchedData.find(lookupDataItem =>
      lookupDataItem.category == 'recommand' && `${lookupDataItem.name} ${lookupDataItem.label} ${lookupDataItem.source}`.toLowerCase().includes(value)
    );
    //检测全部中是否有值
    const checkAll = searchedData.find(lookupDataItem =>
      `${lookupDataItem.name} ${lookupDataItem.label} ${lookupDataItem.source}`.toLowerCase().includes(value)
    );
    // 检测推荐中是否有数据
    this.noRecommandData = !checkRecommand ? true : false;
    // 检测全部中是否有数据
    this.noAllData = !checkAll ? true : false;
  }

  /** 搜索项 */
  onSearchValueChanged(searchValue) {
    const searchedData = this.chooseRecommand ? this.formData : this.formAllDataCopy;
    if (searchedData) {
      const value = this.handleSearchedValue(searchValue);
      this.checkValueExists(searchedData, value);
      searchedData.forEach(formDataItem => {
        let combinedString = `${formDataItem.name} ${formDataItem.label} ${formDataItem.source}`;
        const selectedItem = combinedString.toLowerCase();
        formDataItem.hide = selectedItem.includes(value) == false ? true : false;
      })
    }
    this.formData = cloneDeep(searchedData);
    return this.formData;
  }

  /** 用户选择值 */
  getFormDataItem(selectedformDataItem) {
    this.formData.forEach(formDataItem => {
      if (selectedformDataItem.label == formDataItem.label) {
        formDataItem.active = !formDataItem.active;
        this.selectedCommand = cloneDeep(selectedformDataItem);
      }
      else {
        formDataItem.active = false;
      }
    })

  }

  /** 
   * 事件订阅：补充命令所在的组件ID属性
   */
  private adaptSubscription(declarations: any, targetComponentId: string) {
    if (!declarations || !declarations.commands) {
      return;
    }
    const subscriptions = this.domService.getComponentSubscriptions();
    if (subscriptions.length === 0) {
      return;
    }
    const currentSubs = subscriptions.filter(s => s.targetComponent === targetComponentId);
    if (!currentSubs || currentSubs.length === 0) {
      return;
    }
    const commandDeclarations = declarations.commands as DeclarationCommand[];

    currentSubs.forEach(subscription => {
      const dec = commandDeclarations.find(d => d.code === subscription.invoke);
      if (dec && dec.componentId) {
        subscription.invokeComponentId = dec.componentId;
      }
    });
  }


  /** 用户点击确定时调用postApi传出参数 */
  clickConfirm() {
    if (this.selectedCommand && this.selectedCommand['active']) {
      const http = this.injector.get(HttpClient);
      const relativePath = this.editorParams.relativePath || '';
      const path = '/api/dev/main/v1.0/mdservice/pickMetadata?currentPath=' + relativePath;
      const body = this.selectedCommand.data;
      const headerOption = {
        headers: new HttpHeaders({ 'Content-Type': 'application/json' })
      }
      return http.post(path, body, headerOption).subscribe(data => {
        data['metadata']['processMode'] = this.selectedCommand.data['processMode'] === 'interpretation' ? 'interpretation' : 'general';
        this.selectedMetadata(data['metadata']);
      });
    }
    else {
      this.notifyService['info']('未选择表单');
      return null;
    }
  }

  /** 清空搜索内容 */
  onClear() {
    this.formData = this.onSearchValueChanged('');
  }

  selectedMetadata($event) {
    if (!$event) {
      return;
    }
    const { content, ...frmInfo } = $event;
    let frmContent = JSON.parse(content).Contents;
    if (typeof (frmContent) === 'string') {
      frmContent = JSON.parse(frmContent);
    }
    // 包含路由组件的表单 暂不支持预览
    const componentStr = JSON.stringify(frmContent.module.components);
    if (componentStr.includes(DgControl.RouteContainer.type)) {
      this.notifyService.warning('暂不支持引入包含子路由的表单');
      return;
    }

    // 若选择的组件与之前相同，则不再生成新的id
    let id = ''; const radomNum = Math.random().toString(36).substr(2, 4);
    if (!this.value) {
      id = frmInfo.code + '-' + radomNum + '-component';
    } else {
      const oldCode = this.value.slice(0, this.value.indexOf('-'));
      if (oldCode === frmInfo.code) {
        id = this.value;
      } else {
        // 更换组件，需要删除原组件声明
        id = frmInfo.code + '-' + radomNum + '-component';
        this.domService.deleteExternalComponent(this.value);
        // TODO删除原组件相关的订阅？？否则会有冗余数据--- 目前对不存在的订阅进行提示。
        // 删除相关订阅
        this.domService.deleteComponentSubscription(this.value);
      }
    }

    const externalInfo = {
      id,
      uri: frmInfo.id,
      name: frmInfo.name,
      code: frmInfo.code,
      fileName: frmInfo.fileName,
      filePath: frmInfo.relativePath,
      nameSpace: frmInfo.nameSpace,
      declarations: [],
      type: this.editorParams.containerType,
      containerId: this.editorParams.containerId,
      useIsolateJs: this.editorParams.useIsolateJs,
      projectName: '',
      serviceUnitPath: ''
    };

    if (frmContent.module) {
      externalInfo.declarations = frmContent.module.declarations;
      externalInfo.projectName = frmContent.module.projectName || '';

      // 截取su路径--用于独立加载js脚本
      const filePathArray = externalInfo.filePath.split('/');
      if (filePathArray.length > 2) {
        externalInfo.serviceUnitPath = filePathArray[0] + '/' + filePathArray[1];
      }

    }
    this.value = externalInfo.id;

    // 修改module节点下的externalComponents数据
    this.domService.setExternalComponent(externalInfo, this.oldCmpId);

    this.adaptSubscription(externalInfo.declarations, id);

    const component = externalInfo.id + '-' + frmContent.module.id + '-' + 'root-component';
    this.submitModal.emit({
      value: this.value, parameters: {
        component,
        uri: frmInfo.id
      }
    });
  }

  clickCancel() {
    this.closeModal.emit();
  }
  /** 去重*/
  getUniqueData(data) {
    if (data) {
      let value = cloneDeep(data);
      for (let i = 0; i < value.length; i++) {
        for (let j = i + 1; j < value.length; j++) {
          if (value[i]['id'] == value[j]['id']) {
            value.splice(j, 1);
            j--;
          }
        }
      }
      data = cloneDeep(value);
    }
    return data;
  }

  onPageChange(page: { pageIndex: number }) {
    if (this.pageIndex !== page.pageIndex) {
      this.pageIndex = page.pageIndex;
      this.paginationOptions.currentPage = page.pageIndex;
    }
  }

  /** 接口数据超过1000条时，重新调取所有数据 */
  reinvokeInterface(data) {
    if (data['page']) {
      const totalNum = data['page']['total'] || 0;
      if (totalNum > 1000) {
        const http = this.injector.get(HttpClient);
        const relativePath = this.editorParams.relativePath;
        return http.get('/api/dev/main/v1.0/mdservice/unionmdlist?path=' + relativePath + '&pageIndex=1&pageSize=' + totalNum + '&metadataTypeList=.frm', {
          headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
          responseType: 'json'
        }).subscribe(data => {
          this.formAllData = cloneDeep(this.getFormData(data, 'all'));
          this.formAllDataCopy = cloneDeep(this.formAllData);
        });
      }
    }
  }
}
